package gw.com.android.ui.views;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import static android.animation.ValueAnimator.INFINITE;

/**
 * @author jett
 * @since 2017-11-29.
 */
public class WaveView extends View {

    private static final int COLUMN_COUNT = 3;
    private static final int DURATION = 400;

    private int mWidth;
    private int mHeight;
    private Paint mPaint;
    private float value1;
    private float value2;
    private float value3;

    private int columnWidth;
    private int gapWidth;

    private ValueAnimator firstAnim;
    private ValueAnimator secondAnim;
    private ValueAnimator thirdAnim;

    public WaveView(Context context) {
        super(context);
        init();
    }

    public WaveView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setMinimumWidth(30);
        setMinimumHeight(30);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.WHITE);
        startWave();
    }

    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        if (visibility == VISIBLE) {
            startWave();
        } else {
            stopWave();
        }
    }

    public void startWave() {
        stopWave();
        firstAnim = ValueAnimator.ofFloat(0, 1);
        secondAnim = ValueAnimator.ofFloat(0, 1);
        thirdAnim = ValueAnimator.ofFloat(1, 0);

        firstAnim.setDuration(DURATION);
        secondAnim.setDuration(DURATION);
        thirdAnim.setDuration(DURATION);
        firstAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                value1 = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        secondAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                value2 = (float) animation.getAnimatedValue();
            }
        });
        thirdAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                value3 = (float) animation.getAnimatedValue();
            }
        });
        firstAnim.setRepeatMode(ValueAnimator.REVERSE);
        secondAnim.setRepeatMode(ValueAnimator.REVERSE);
        thirdAnim.setRepeatMode(ValueAnimator.REVERSE);
        firstAnim.setRepeatCount(INFINITE);
        secondAnim.setRepeatCount(INFINITE);
        thirdAnim.setRepeatCount(INFINITE);

        firstAnim.start();
        secondAnim.setStartDelay(DURATION / 2);
        secondAnim.start();
        thirdAnim.start();
    }

    public void stopWave() {
        if (firstAnim != null && firstAnim.isRunning()) {
            firstAnim.end();
        }
        if (secondAnim != null && secondAnim.isRunning()) {
            secondAnim.end();
        }
        if (thirdAnim != null && thirdAnim.isRunning()) {
            thirdAnim.end();
        }
        firstAnim = null;
        secondAnim = null;
        thirdAnim = null;
    }

    public void setWaveColor(int color) {
        mPaint.setColor(color);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();

        columnWidth = mWidth / (COLUMN_COUNT + (COLUMN_COUNT - 1) / 2);
        gapWidth = columnWidth / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mWidth <= 0 || mHeight <= 0) {
            return;
        }
        if (columnWidth <= 0) {
            return;
        }

        float minTop = 0;
        float maxTop = mHeight * 0.8F;
        float distance = maxTop - minTop;

        float left = 0;
        float top = maxTop - value1 * distance;
        float right = columnWidth;
        float bottom = mHeight;
        canvas.drawRect(left, top, right, bottom, mPaint);

        left += columnWidth + gapWidth;
        right = left + columnWidth;
        top = maxTop - value2 * distance;
        canvas.drawRect(left, top, right, bottom, mPaint);

        left += columnWidth + gapWidth;
        right = left + columnWidth;
        top = maxTop - value3 * distance;
        canvas.drawRect(left, top, right, bottom, mPaint);
    }

}
